#134
Nov 03, 2008

Paperclip

Need to add image attachments to a model? See how with paperclip in this episode.
Tags: plugins
Download (15.6 MB, 7:46)
alternative download for iPod & Apple TV (9.9 MB, 7:46)

Resources

script/plugin install git://github.com/thoughtbot/paperclip.git
script/generate paperclip product photo
rake db:migrate
# models/product.rb
has_attached_file :photo, :styles => { :small => "150x150>" },
                  :url  => "/assets/products/:id/:style/:basename.:extension",
                  :path => ":rails_root/public/assets/products/:id/:style/:basename.:extension"

validates_attachment_presence :photo
validates_attachment_size :photo, :less_than => 5.megabytes
validates_attachment_content_type :photo, :content_type => ['image/jpeg', 'image/png']
<!-- products/show.html.erb -->
<%= image_tag @product.photo.url(:small) %>

<!-- products/_form.html.erb -->
<% form_for @product, :html => { :multipart => true } do |f| %>
  ...
  <%= f.file_field :photo %>
  ...
<% end %>

RSS Feed for Episode Comments 71 comments

1. Jim Nov 03, 2008 at 00:25

Just what I needed - thanks!


2. David Trasbo Nov 03, 2008 at 01:03

Paperclip looks like a pretty good alternative to attachment_fu.


3. Sascha Nov 03, 2008 at 01:11

Thanks Ryan for that railscast! A few weeks ago I was build a function like this in my app with attachment_fu and ImageScience. Are there any drawbacks in relation to your solution?


4. Alex Zavalny Nov 03, 2008 at 01:41

Hi Ryan! One question! Is it possible to make Paperclip work if I need my model to have many attachments? If it's not possible, maybe you know some other plugins?


5. Erik Dahlstrand Nov 03, 2008 at 01:59

@Alex
Have a look at this tutorial: http://www.practicalecommerce.com/blogs/post/432-Multiple-Attachments-in-Rails

It's for attachment_fu but it's the same concept for paperclip.

Also there is a polymorphic paperclip plugin, see this tutorial
http://burm.net/2008/10/17/ruby-on-rails-polymorphic-paperclip-plugin-tutorial/


6. Alexei Nov 03, 2008 at 02:01

As far as I know there is a polymorphic paperclip plugin. Maybe that's what you are looking for, Alex.

I liked paperclip plugin, but I need to sort out what to do with many attachments.


7. Jim Neath Nov 03, 2008 at 02:07

Thanks for the link, Ryan.

It's good to see more people using Paperclip.


8. leethal Nov 03, 2008 at 02:11

I really really want to stress that uploading files is _easy_!

http://gist.github.com/20698

That gist is just a file upload, though. No file size and/or mime type validations there. Or imagemagick fanciness.


9. PanosJee Nov 03, 2008 at 02:13

Hi Ryan, great post as always. I would like to ask what about pdfs or docs ? Just change the filetype ?


10. Tex Nov 03, 2008 at 02:59

Great presentation Ryan, I choose paperclip some time ago and I'm very happy with it.

I remember that you can use model attributes into url/path using interpolations (great feature !!!).


11. Aditya Sanghi Nov 03, 2008 at 03:14

Really simple and useful screencast once again. +1 to panosjee, I'd love to be able to have multiple pics on the model as well as clip more than just images.


12. Jim Neath Nov 03, 2008 at 03:19

@PanosJee - You can change the file type validations if you want to upload pdfs or docs. Paperclip can handle pretty much anything you want to upload

@Aditya Sanghi - If you want to attach multiple uploads to a model just create an assets model using paperclip and use a has_many relationship


13. Chess Nov 03, 2008 at 04:31

We use paperclip on a current project and it works good except for:

1. When you delete an attachment it does not delete the directory it created for the file. Thus over time you are left with hundreds of empty directories on your server.

2. Take an Outlook email and drag it to your desktop, it'll create a .msg file. Now try to upload that file using a webkit based engine (Chrome, Safari) and Paperclip will crash. No problem with FF or IE.

I've tried to get a solution from Paperclip Google group but the developers have been unresponsive to the second problem and don't think the first problem is a problem.


14. David Trasbo Nov 03, 2008 at 05:35

@Chess:

1. I guess you could set up a rake task that removes the empty directories?

2. They should definitely fix that. Maybe they don't know how...


15. Jose Nov 03, 2008 at 05:38

Why not attachment_fu?


16. Zachary Denison Nov 03, 2008 at 05:40

Is this a good solution to use if you have a model that needs to 'has_many' photos? its not clear how you would adapt this to the situation where you need to have a variable number of photos associated with a model.

Thanks for any insight on this.


17. Chris Nov 03, 2008 at 05:42

Hey Ryan

Another good one and again we seem strangely in sync with your railscasts - Rob posted about Paperclip on our blog yesterday - including instructions to help long suffering (in general!) windows users out:

http://thewebfellas.com/blog/2008/11/2/goodbye-attachment_fu-hello-paperclip

Chris


18. Chris Nov 03, 2008 at 05:44

@zachary: there's a plugin on github for polymorphic paperclips. or you can setup polymorphism manually (which is what i did) as i didn't want an additional table in the middle.


19. Nilesh Nov 03, 2008 at 06:58

Great screencast, Ryan! A small note to add. To refresh the thumbnails after a change in the attachment models, there is no need to upload the images again. You can simply run this --

rake paperclip:refresh


20. Ryan Bates Nov 03, 2008 at 07:08

For those wondering how to handle the case where you want many photos per product. All you need to do is create a second model (ProductPhoto) with a one-to-many association to product. Use paperclip on ProductPhoto and there you go. Now a product can have many photos.

@leethal, thanks! It's nice to see file uploads on their own is fairly simple.

@Chess, it's an open source project, so if the developers aren't willing/able to fix these problems you can always fork it on GitHub and fix them. Maybe someone already has as there are a number of forks already.

@Nilesh, cool, didn't know about that Rake task. Thanks! That's one thing, I think Paperclip could use more complete documentation.


21. Ben Nov 03, 2008 at 15:09

This is very cool.

@Jim Neath - sounds like paperclip can handle any file type, great!

Is it possible to store the attachments in the DB? I'd like to store attachments in the database for things like drivers licenses, social security cards, etc.


22. AdrianoD Nov 03, 2008 at 17:13

using windows i always find myself with C:/InstantRails-2.0-win/ruby/bin/mongrel_rails: No such file or directory - iden
tify "C:/DOCUME~1/Owner/LOCALS~1/Temp/stream.2748.0"
 and not being able to covnert to styles small even with imagemagick and rmagick installed in the log file i just saw
Rendering C:/InstantRails-2.0-win/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/templates/rescues/layout.erb (not_found)

any idea how can i fix it (switching for linux aint an option right now)
thanks in advance


23. Carl Nov 03, 2008 at 19:32

@Ben,

I used this as a basis for storing some simple pictures in my database:

http://dizzy.co.uk/ruby_on_rails/contents/store-file-uploads-in-database

I wasn't trying to do exactly the same thing as the author, but it wasn't too hard to adapt. Having said that, I'm not sure it is better than the way Paperclip or Attachment_fu does it by default. I can see pros and cons both ways.


24. Lenart Nov 04, 2008 at 01:12

@AdrianoD: I switched completely to cygwin and use ruby (on rails) inside there. I think I have less problems with plugins etc. Maybe you should try also.

Here are all the links I needed to set it up: http://delicious.com/lenart/cygwin


25. José Mota Nov 04, 2008 at 03:02

I almost fell off the chair with that! Great news! Just what I needed!


26. Thomas Nov 04, 2008 at 12:03

Did anyone test if an attacker can concatenate code to the image and have it execute when the image displays?


27. StartBreakingFree.com Nov 04, 2008 at 12:41

I almost cried watching this! :) Do you have any idea how long it took me to get attachment_fu working and cropping and ImageScience and RMagick and memory leaks and ImageMagick etc and then you did it in 5 minutes arg!!!!!

Great stuff, thanks Ryan.


28. Sergey Nov 04, 2008 at 12:43

awesome, thanks! just what I was looking for to replace attachment_fu, which gives me some headache with kind of restricted validation.


29. Jim Nov 04, 2008 at 18:15

@AdrianoD

I struggled with the same problem but running under passenger. The solution for me was to add the following file to the initializers:-

# config/initializers/paperclip.rb
Paperclip.options[:image_magick_path] = "/usr/local/bin"

Restart the server and voila! (at least for me YMMV!)


30. Michael Nov 05, 2008 at 05:35

Ryan, I love your screencast again. Thanks for all your nice work!

I have one question. I try to save photos on a one to many relationship. It works well only i want to change the path. I want to have a parent_id in the url and the path.

ive got a room and a room has many pictures

This isnt working:

:path => ":rails_root/public/assets/room_photos/#{self.room.id}/:id/:style/:basename.:extension"

:parent_id or :room_id isnt working as well.

Somebody has an idea?


31. Anlek Nov 05, 2008 at 08:09

Great RailsCast, but can you explain why use paperclip over attachment_fu? Some comments talked about it briefly but not enough for me to know if it's worth switching my code (from attachment_fu to paperclip).

Thanks,

Andrew


32. Ryan Bates Nov 05, 2008 at 14:24

@AdrianoD, Windows is mentioned at the beginning of this article, so that might help.

http://tinyurl.com/5nrl3k

@Thomas, that's an interesting question and I haven't looked into it. I don't think any code would be executed on the server side, but maybe when the client renders it? However, if so then I think this would be a security flaw with the image codec itself and not necessarily with our Rails app.

@Michael, yes that's possible by making a custom interpolation. It's mentioned near the end of this article.

http://tinyurl.com/5nrl3k

@Andrew, if you're using attachment_fu with good success then I wouldn't bother switching. But for new projects I recommend paperclip for these reasons:

- a separate attachment model isn't necessary.
- image library isn't required (unless you need to resize)
- smaller memory footprint

Those are just some things I've heard, but honestly haven't done much research.


33. James Nov 06, 2008 at 07:39

@Ryan, for those of us that choose to switch from attachment_fu to paperclip, is there any way to continue to use the separate attachment model?


34. Ryan Bates Nov 06, 2008 at 08:34

@James, yep. I'm not sure of all the steps involved. But you can keep your attachment model and just apply paperclip to that.


35. Jonathan Nelson Nov 06, 2008 at 12:54

paperclip is by far the best alternative to attachment_fu....i no longer like attachment_fu, so thank you Ryan.


36. Achim Nov 06, 2008 at 18:52

there is an other very smart plugin for fileuploads called uploadcolumn. i use it on several projects and at first sight it is exact the same thing as paperclip ..

http://uploadcolumn.rubyforge.org/


37. Johnny Nov 07, 2008 at 07:16

Thanks Ryan! I love paperclip. I have a suggestion for a future episode...charting/graphing!


38. Benjamin Quorning Nov 08, 2008 at 06:34

I am using Paperclip to upload photographs, and wanted to have the DateTime the photo was taken extracted from the uploaded file's EXIF metadata, and saved as an attribute on my Picture model.

After some hopeless attempts using before_save and after_save callbacks, I ended up just overwriting Paperclip's photo= method: http://pastie.org/310107


39. alxz Nov 08, 2008 at 07:17

And what about width="" height=""?

It would be great to save width and height of resized image in its file name...


40. Steve Nov 10, 2008 at 17:32

Is there a way to upload an image by typing the url of the image location, instead of using the file_field. Ive been looking for a good tutorial for this and cant seem to find any. Thanks


41. Benjamin Quorning Nov 11, 2008 at 03:39

@Steve, take a look at http://almosteffortless.com/2008/10/24/easy-upload-via-url-with-attachment_fu/

That's how you do it with attachment_fu, though – dunno if you can do the same trick using Paperclip.


42. Jon Nov 11, 2008 at 08:32

Steve, Benjamin - checkout the paperclip_url_support project over at github.


43. Steve Nov 13, 2008 at 11:42

Hey guys... thanks for the suggestions... got it to work!!!


44. Laser Lemon Nov 14, 2008 at 06:58

Great episode! I set up Paperclip on my local machine (Leopard, running Passenger) and after commenting out the "rescue" in Paperclip::Attachment#post_process, I get this crappy "/tmp/stream.3916.0 is not recognized by the 'identify' command" error.

I have my ImageMagick path set correctly and proper permissions. What gives?


45. Mark Nov 15, 2008 at 03:39

Sorry for asking, but when I run script/plugin install git://github.com/thoughtbot/paperclip.git on windows I only get information: removing: D:/testy/vendor/plugins/paperclip/.git

What should I do to install plugin from git on windows?


46. henry Nov 17, 2008 at 21:22

easier than has_attachment , for images uploading


47. Yves Nov 18, 2008 at 05:36

Hi Laser Lemon,

the same issue here. Did you fix it already?


48. Ryan Nov 18, 2008 at 16:45

when i use git to install paperclip via "script/plugin install git://github.com/thoughtbot/paperclip.git", i get the following error (after which, if i try to use the paperclip generator, it says it doesn't exist)...

http://pastie.org/318325

If you could give me ANY help i would appreciate it. i can't tell if my git install is screwed up, or if i'm missing something. everyone else seems to have an easy time installing this.


50. Koen Van der Auwera Nov 19, 2008 at 03:01

Hi Yves, Laser Demon, all,

I got it working with an intializer: http://gist.github.com/26476 - Passenger + Paperclip that is.

via http://www.fuzzylizard.com/archives/2008/07/05/954/


50. Nick Nov 19, 2008 at 07:19

Hey Bryan, as a rails newbi from Germany I love your casts. And with regards to paperclip: my project uses file_column but I would like to switch to paperclip. Do you know how I can make the switch smooth so that I cann still use the so far uploaded Files (path: system/user/picture/<id>/<filename>)? Great if you could help me.
All the best. Im a big fan.
Nick


51. Ronen Nov 19, 2008 at 07:24

@Laser Lemon

I am getting the same error on two different machines, a vista and an XP.

I do not have imagemagick installed.

AppData/Local/Temp/stream.2620.0 is not recognized by the 'identify' command.


52. Ronen Nov 19, 2008 at 07:42

Solved my issue by installing ImageMagick-6.4.5-8-Q16-windows-dll.exe


53. jc Nov 19, 2008 at 08:16

Any recommendations against using fleximage? http://github.com/Squeegy/fleximage/wikis

paperclip looks very easy, but so does fleximage. The one thing that really catches my attention about it is the dynamic resizing:
http://github.com/Squeegy/fleximage/wikis/rendering

From what I understand it will render whatever size you want at anytime after the upload, so you don't have to figure out all your sizes in advance and then build your own rake task if you want to make a new size.


54. Steffen Schmidt Nov 19, 2008 at 13:38

Hi @all,

do anyone of you know how to include by paperclip generated thumbnails to the to_xml methode?
If I use methods I can specify an array with fields but there I can't say the variation (e.g. small part of photo).

Any ideas?
Thanks for your help,
Steffen


56. EH Nov 20, 2008 at 14:59

SPAM CLEANUP ON AISLE 4


56. Jon Nov 22, 2008 at 07:41

For some reason when I used Paperclip to resize images for thumbnails it produced files of 0bytes. I had to specify in the model that I wanted jpg files created even if the original was a jpg.

In the following instance the 'small' picture would be fine, but the 'regular' size would be corrupt.

has_attached_file :photo, :styles => { :small => ["100x100#", :jpg], :regular => "300>"}


57. kamel Nov 22, 2008 at 09:28

I'm using paper clip to upload documents (doc and rtf) it workd fine for a while then it stops suddenly! I can't figure out what's the problem but when I restart my mongrel instance it works fine again... anyone knows anything about it??


58. kamel Nov 22, 2008 at 09:31

Checked my mongrel log and found this: Error reading HTTP body: #<RuntimeError: Socket read returned insufficient data: 10379>


59. Yves Nov 23, 2008 at 05:18

Hi,

thanks Koen Van der Auwera.
Another way for solving this is setting PATH as environment variable for Mac OS X 10.5 in /System/Library/LaunchDaemons/org.apache.httpd.plist:

http://gist.github.com/28112


60. Yves Nov 23, 2008 at 05:30

One more thing… I haven't seen a Fileupload plugin which is capable of keeping the temporar file of an upload if the validation fails.

For instance we've the model Medium which has_attachment :file and validates_presence_of :comment. If we left out the comment but specified a :file (let's say a big one... 200MB...) the validation will fail and the data is lost.
It's pretty annoying if you have to upload the file again.

As a workaround you can reflect the validation on client side... but it's not a solution for the problem.


61. Jon Nov 23, 2008 at 06:33

Yves i'm nearly sure I've done that in the past with attachment_fu. I wanted to use the mp3-info library to extract data from a sound file upload even if the upload failed in validations.

You can use a before_save method in the model to access the file (using self.temp_path) before it has been saved. You can then do anything you want with it.

Or you could write your own validations, or modify the existing ones.


63. Tom Karlo Nov 26, 2008 at 06:54

For anyone on OSX getting the ".../tmp/stream.3916.0 is not recognized by the 'identify' command" error, it's probably that identify is not in your path. The macport install and other installs do not always seem to get this right.

To fix:
* check if "identify" is in your path from the same terminal where you're about to run your "ruby server/script" command - just try to run it from the terminal prompt
* if it won't run, try entering these commands:
tom:~ tom$ export MAGICK_HOME="/opt/local/"
tom:~ tom$ export PATH="$MAGICK_HOME/bin:$PATH"
tom:~ tom$ export DYLD_LIBRARY_PATH="$MAGICK_HOME/lib"
(you may have to adjust MAGICK_HOME to match your install)

After that, try running identify again from your RoR site's root dir. It should now work. If it does, run your server and see if your photos now work.

(You'll want to make sure the above PATH changes are made permanent if this fix does help.)


64. Andrés Mejía Nov 30, 2008 at 14:20

Hello Ryan,

Do you know if it's possible to create an attachment inside a controller?

I mean, I have some text stored in a string. I want to create an attachment that is a plain text file containing the contents of that string into a given model object.

Is this possible?
Thanks!


65. Pierre Dec 03, 2008 at 07:52

default_url and default_style are also useful options.
See paperclip.rb in the code for explainations.


66. Patrick Berkeley Dec 06, 2008 at 20:14

Like a bunch of other people on here, I'm setting up a model with multiple attachments.

I've followed this Railscast and Ryan's article on multiple models in one form in Advanced Rails Recipes (#13).

Here's the code I have so far:
http://gist.github.com/33011

As you can see I'm receiving an 'unknown attribute' error. I think this has to do with the way I'm using a new attribute writer method for in the model, and I don't think paperclip has run at that point. So, there is no attachment attribute yet, and thus the error.

Any advice is appreciated.

P.S. I've looked at the other articles mentioned above on polymorphic associations with paperclip, but none of them worked for me.


67. Bryan Buchs Dec 08, 2008 at 06:34

I was having a heck of a time getting Paperclip to generate thumnails, even though I have working copies of ImageMagick and RMagick installed. My IM was built from source and installed to /usr/local/bin. The solution was to add a line to my development.rb:

Paperclip.options[:image_magick_path] = '/usr/local/bin/'

Hope that helps someone else out!


68. Patrick Berkeley Dec 08, 2008 at 14:48

For anyone who's interested I've updated a gist with a working example of multiple file attachments using Paperclip.

http://gist.github.com/33011

Notes about the gist:
1. Page has many Assets
2. Asset has Paperclip attachment
3. Paperclip attachment is called 'file'


68. kamel Dec 14, 2008 at 16:02

no one has any info about: Error reading HTTP body: #<RuntimeError: Socket read returned insufficient data: 10379>??


69. jordan shose Jan 06, 2009 at 01:07

good, thanks for your infos

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player